package justbuy.payment.action;

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.inject.Inject;

import justbuy.payment.service.PaymentService;
import justbuy.payment.service.PaymentServiceManager;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.ironrhino.core.metadata.AutoConfig;
import org.ironrhino.core.metadata.JsonConfig;
import org.ironrhino.core.struts.BaseAction;
import org.ironrhino.core.util.RequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@AutoConfig
public class GatewayAction extends BaseAction {

	private static final long serialVersionUID = 8175406892708878896L;

	protected static Logger log = LoggerFactory.getLogger(GatewayAction.class);

	public static final String PARAMETER_NAME_ORDER_NUMBER = "orderNumber";

	private String orderNumber;

	private Map<String, String> paymentServices;

	@Inject
	private transient PaymentServiceManager paymentServiceManager;

	public Map<String, String> getPaymentServices() {
		return paymentServices;
	}

	public String getOrderNumber() {
		return orderNumber;
	}

	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}

	@JsonConfig(root = "paymentServices")
	public String execute() {
		paymentServices = new LinkedHashMap<String, String>();
		for (PaymentService p : paymentServiceManager.getPaymentServices())
			paymentServices.put(p.getName(), p.getLogo());
		return JSON;
	}

	public String form() {
		if (StringUtils.isBlank(orderNumber))
			return NONE;
		PaymentService p = paymentServiceManager.lookup(getUid());
		Map<String, String> map = new HashMap<String, String>();
		for (Map.Entry<String, String[]> entry : ServletActionContext
				.getRequest().getParameterMap().entrySet()) {
			String name = entry.getKey();
			if (name.equals("code") || name.equals("title")
					|| name.equals("amount"))
				continue;
			String[] value = entry.getValue();
			if (value != null && value.length > 0)
				map.put(name, value[0]);
		}
		Map<String, String> params = RequestUtils
				.getParametersMap(ServletActionContext.getRequest());
		params.remove(PARAMETER_NAME_ORDER_NUMBER);
		String html = p.generateHtmlForm(orderNumber,
				RequestUtils.getBaseUrl(ServletActionContext.getRequest()),
				params);
		try {
			ServletActionContext.getResponse().getWriter().write(html);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return NONE;
	}

	public String ret() {
		try {
			PaymentService p = paymentServiceManager.lookup(getUid());
			p.handleReturn(RequestUtils.getParametersMap(ServletActionContext
					.getRequest()));
			targetUrl = p.getOrderUrl(orderNumber);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return REDIRECT;
	}

	public String ntf() {
		PaymentService p = paymentServiceManager.lookup(getUid());
		String result = p.handleNotify(RequestUtils
				.getParametersMap(ServletActionContext.getRequest()));
		if (StringUtils.isNotBlank(result))
			try {
				Writer w = ServletActionContext.getResponse().getWriter();
				w.write(result);
				w.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		return NONE;
	}

	public String ship() {
		try {
			PaymentService p = paymentServiceManager.lookup(getUid());
			p.ship(orderNumber,
					RequestUtils.getBaseUrl(ServletActionContext.getRequest()));
			targetUrl = p.getOrderUrl(orderNumber);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return REDIRECT;
	}

	public String refund() {
		try {
			PaymentService p = paymentServiceManager.lookup(getUid());
			p.refund(orderNumber,
					RequestUtils.getBaseUrl(ServletActionContext.getRequest()));
			targetUrl = p.getOrderUrl(orderNumber);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return REDIRECT;
	}

}
